本节题目来自王道单科37页。说不定哪天就放弃了在电脑上敲代码了,好费时啊啊啊啊。
6、有一个带头结点的单链表L,设计一个算法使其递增有序。
分析:排序问题。如果没有说不能用辅助数组的话,可以把它复制进数组,快排后再尾插法插入链表中。
这里我们直接在链表中用直接插入排序,即先把前面的一个元素先看作有序,从第二个元素开始遍历。设立三个指针,p用于遍历,pre用于记录插入位置,r用于记录p后继指针,防止断链。r=p->next; p=r; 事实上是经常会有的操作。
void Sort(LinkList &L){ LNode *p,*pre,*r; p=L->next; r=p->next; //r保持*p后继结点指针,以保持不断链 p->next=NULL; //构造只含有一个数据元素的有序表 p=r; //不要忘了这句 ,从第二个元素开始遍历 while(p!=NULL){ r=p->next; pre=L; //pre每次都要在前面的有序表中从头遍历 while(pre->next!=NULL&&pre->next->data<p->data) //找到有序表中第一个比p大的结点,并插到其前面 pre=pre->next; p->next=pre->next; pre->next=p; p=r; } }
7、删除给定单链表中所有介于给定两个值之间的元素
和之前的顺序表上面的都是差不多
void delete_st(LinkList &L,int min,int max){ // 删除给定单链表中所有介于给定两个值之间的元素 LNode *p,*pre; p=L->next; pre=L; while(p!=NULL){ if(p->data<max&&p->data>min){ pre->next=p->next; free(p); p=pre->next; } else{ //注意区分和删除最小值的代码。这个有涉及在循环里面删除结点,所以不满足条件的时候才扫描下一个结点 pre=p; p=p->next; } } }
8、给定两个单链表,编写算法找出两个链表的公共结点
LinkList find_Common(LinkList A,LinkList B){ LNode *p=A->next,*q=B->next; int dist; LinkList longlist,shortlist; int lenA=GetLength(A); int lenB=GetLength(B); if(lenA>lenB){ longlist=A->next;shortlist=B->next; dist=lenA-lenB; } else{ longlist=B->next;shortlist=A->next; dist=lenB-lenA; } while(dist--)longlist=longlist->next; while(longlist!=NULL){ if(longlist==shortlist)return longlist; else{ longlist=longlist->next; shortlist=shortlist->next; } } return NULL; }
9、按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间。
void Min_Delete(LinkList &L){ LNode *pre,*p; LNode *minpre,*minp; while(L->next!=NULL){ pre=L;minpre=pre; p=L->next;minp=p; while(p!=NULL){ if(p->data<minp->data){ minpre=pre; minp=p; } pre=p; p=p->next; } printf("%d ",minp->data); minpre->next=minp->next; free(minp); } }
10、将一个带头节点的单链表A分解为两个带头节点的单链表A和B,使得A表中含有原表中序号为奇数的元素,而B表中含有原表中序号为偶数的元素,且保持其相对顺序不变。
第一种:设置访问序号变量。
void DisCreate1(LinkList &A,LinkList &B){ B=(LinkList)malloc(sizeof(LNode)); B->next=NULL; LNode *p; LNode *ra=A; LNode *rb=B; p=A->next; A->next=NULL; while(p!=NULL){ rb->next=p; rb=p; ra->next=p->next; ra=p->next; p=p->next->next; } ra->next=NULL; rb->next=NULL; }
第二种,不用设置序号变量,一次处理两个,第一个处理的结点就是奇数号结点,第二个处理的结点就是偶数号结点。
void DisCreate2(LinkList &A,LinkList &B){ B=(LinkList)malloc(sizeof(LNode)); B->next=NULL; int i=0; LNode *p; LNode *ra=A; LNode *rb=B; p=A->next; A->next=NULL; while(p!=NULL){ i++; if(i%2==0){ rb->next=p; rb=p; } else{ ra->next=p; ra=p; } p=p->next; } ra->next=NULL; rb->next=NULL; }
11、设C={a1,b1,a2,b2,......an,bn}为线性表,采用带头结点的单链表表示,设计一个就地算法将其拆分为两个线性表,分别为A={a1,a2,a3.an},和{b1,b2,b3.,,,bn}
LinkList DisCreateAB(LinkList &A){ LinkList B=(LinkList)malloc(sizeof(LNode)); B->next=NULL; LNode *p,*s; LNode *ra=A; p=A->next; while(p!=NULL){ s=p->next; p->next=B->next; B->next=p; p=s; ra->next=p; ra=p; p=p->next; } ra->next=NULL; return B; }